class YOLOv8CSPDarknet(BaseBackbone):
    print("this YOLOv8CSPDarknet is from the ENV MARK-Y2 ConvWithCBAM")
    # Log4
    # From left to right:
    # in_channels, out_channels, num_blocks, add_identity, use_spp
    # the final out_channels will be set according to the param.
    arch_settings = {
        'P5': [[64, 128, 3, False, False], [128, 256, 6, False, False],
               [256, 512, 6, True, False], [512, 0, 3, True, True]],
    }

    def __init__(self,
                 arch: str = 'P5',
                 last_stage_out_channels: int = 1024,
                 plugins: Union[dict, List[dict]] = None,
                 deepen_factor: float = 1.0,
                 widen_factor: float = 1.0,
                 input_channels: int = 3,
                 out_indices: Tuple[int] = (2, 3, 4),
                 frozen_stages: int = -1,
                 norm_cfg: ConfigType = dict(
                     type='BN', momentum=0.03, eps=0.001),
                 act_cfg: ConfigType = dict(type='SiLU', inplace=True),
                 norm_eval: bool = False,
                 init_cfg: OptMultiConfig = None):
        self.arch_settings[arch][-1][1] = last_stage_out_channels
        super().__init__(
            self.arch_settings[arch],
            deepen_factor,
            widen_factor,
            input_channels=input_channels,
            out_indices=out_indices,
            plugins=plugins,
            frozen_stages=frozen_stages,
            norm_cfg=norm_cfg,
            act_cfg=act_cfg,
            norm_eval=norm_eval,
            init_cfg=init_cfg)

    def build_stem_layer(self) -> nn.Module:
        """Build a stem layer with CBAM integrated."""
        return ConvWithCBAM(
            self.input_channels,
            make_divisible(self.arch_settings['P5'][0][0], self.widen_factor),
            kernel_size=3,
            stride=2,
            padding=1,
            norm_cfg=self.norm_cfg,
            act_cfg=self.act_cfg
        )

    def build_stage_layer(self, stage_idx: int, setting: list) -> list:
        """Build a stage layer with CBAM integrated.

        Args:
            stage_idx (int): The index of a stage layer.
            setting (list): The architecture setting of a stage layer.
        """
        in_channels, out_channels, num_blocks, use_adown, use_spp = setting

        in_channels = make_divisible(in_channels, self.widen_factor)
        out_channels = make_divisible(out_channels, self.widen_factor)
        num_blocks = make_round(num_blocks, self.deepen_factor)
        expand_ratio = float(0.5)

        mid_channels = int(out_channels * expand_ratio)       # c3
        rep_channels = int(mid_channels * expand_ratio)          # c4

        stage = []
        if use_adown:
            sc_down_layer = ADown(in_channels, out_channels)
            stage.append(sc_down_layer)
        else:
            conv_layer = ConvWithCBAM(  # Replace ConvModule with ConvWithCBAM
                in_channels,
                out_channels,
                kernel_size=3,
                stride=2,
                padding=1,
                norm_cfg=self.norm_cfg,
                act_cfg=self.act_cfg
            )
            stage.append(conv_layer)

        rep_layer = RepNCSPELAN4(
                out_channels,
                out_channels,
                mid_channels,
                rep_channels
            )
        stage.append(rep_layer)

        if use_spp:
            spp = SPPELAN(
                out_channels,
                out_channels,
                768 // 2 
            )
            stage.append(spp)
        return stage

    def init_weights(self):
        """Initialize the parameters."""
        if self.init_cfg is None:
            for m in self.modules():
                if isinstance(m, torch.nn.Conv2d):
                    # In order to be consistent with the source code,
                    # reset the Conv2d initialization parameters
                    m.reset_parameters()
        else:
            super().init_weights()
